package com.hidehai.tw;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 日程排期
 * Created by hidehai on 2015/8/17.
 */
public class CtmCalc {

    /*排期*/
    public static List<Talk> calc(Talk talk){
        List<Talk> talks = new ArrayList<Talk>();
        Date beginDate = new Date();
        talk.setBeginDate(new Date());
        talks.add(talk);
        return talks;
    }

    public static List<Talk> convertTalk(String[] args) throws ParseException {
        List<Talk> talks = new ArrayList<Talk>();
        for(String msg : args){
            Talk talk = parse(msg);
            talks.add(talk);
        }
        return talks;
    }

    /*排期*/
    public static List<Talk> calc(String[] args) throws ParseException {
        List<Talk> talks = new ArrayList<Talk>();
        Date beginTime = parseString("09:00");
        Date lunchTime = parseString("12:00");
        Date eventTime = parseString("17:00");
        Date nextTime = beginTime;
        for(String msg : args){
           Talk talk = parse(msg);
            globalRule(talk);
            talks.add(talk);
        }
        for(Talk talk:talks){
            Date targetDate =null;
            if(nextTime.before(lunchTime)){
                targetDate = lunchTime;
            }else{
                targetDate =eventTime;
                nextTime = parseString("13:00");
            }
            int t = (int) subMinutes(nextTime,targetDate);
            if(talk.getBeginDate() == null && talk.getMinutes() <= t){
                talk.setBeginDate(nextTime);
                talk.setLightning(true);
                nextTime = addMinutes(nextTime,talk.getMinutes());
            }else if(talk.getMinutes() == 0 || talk.getMinutes() >t){
                continue;
            }
        }
        return talks;
    }

    /*Tidy*/
    public static List<Talk> tidy(List<Talk> talks,Date beginDate,Date endDate){
        /*从日程中挑选session1.1 9AM-12PM*/
        /*从日程中挑选seesion1.2 13PM-17PM*/
        Date nextTime = beginDate;
        List<Talk> session = new ArrayList<Talk>();
        int allTime = (int) subMinutes(nextTime,endDate);
        Talk linghtNight = null;
        for(Talk talk:talks){
            if(nextTime.equals(endDate) || nextTime.after(endDate)){
                break;
            }
            if(talk.getMinutes() == null){
                linghtNight = talk;
                continue;
            }
            int t = (int) subMinutes(nextTime,endDate);
             if(talk.getMinutes() >t){
                continue;
            }else if(talk.getBeginDate() == null && talk.getMinutes() <= t ){
                talk.setBeginDate(nextTime);
                nextTime = addMinutes(nextTime,talk.getMinutes());
                session.add(talk);
            }

        }
        if(nextTime.equals(parseString("12:00")) || nextTime.before(parseString("12:00"))){//挑选后，进行特定事项的处理
            session.add(new Talk(parseString("12:00"),"Lunch",null));
        }else if (nextTime.after(parseString("16:00"))){
            if(linghtNight != null && nextTime.before(parseString("17:00"))){   //当天有时间，则进行LightNight
                linghtNight.setBeginDate(nextTime);
                session.add(linghtNight);
                nextTime = addMinutes(nextTime,5);
            }
            session.add(new Talk(nextTime,"Networking Event",null));
        }
        return session;
    }

    public static Map<String,List<Talk>> process(String[] args) throws ParseException {
        Map<String,List<Talk>> results = new LinkedHashMap<String,List<Talk>>();
        List<Talk> talks = new ArrayList<Talk>();
        for(String msg : args){
            Talk talk = parse(msg);
            talks.add(talk);
        }
        results.put("Track1",getTrack(talks));
        results.put("Track2",getTrack(talks));
        return results;
    }

    private static List<Talk> getTrack(List<Talk> talks){
        Date beginTime = parseString("09:00");
        Date lunchTime = parseString("12:00");
        Date nextTime = parseString("13:00");
        Date eventTime = parseString("17:00");

        List<Talk> trackOneAm = tidy(talks,beginTime,lunchTime);
        talks.removeAll(trackOneAm);
        List<Talk> trackOnePm = tidy(talks,nextTime,eventTime);
        trackOneAm.addAll(trackOnePm);
        talks.removeAll(trackOnePm);
        return trackOneAm;
    }

    /* Minute Plus */
    private static Date addMinutes(Date talkDate,int minute){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(talkDate);
        calendar.add(Calendar.MINUTE,minute);
        return calendar.getTime();
    }

    /**/
    private static long subMinutes(Date startDate,Date endDate){
        final int mi = 1000 * 60;
        Calendar startCalendar = Calendar.getInstance();
        startCalendar.setTime(startDate);
        long startTimeInMillis = startCalendar.getTimeInMillis();
        Calendar endCalendar = Calendar.getInstance();
        endCalendar.setTime(endDate);
        long endTimeInMillis = endCalendar.getTimeInMillis();
        return (endTimeInMillis - startTimeInMillis) / mi;
    }

    /*apply rule*/
    private static void globalRule(Talk talk) throws ParseException {
        String subject = talk.getSubject();
        if(subject.equals("Lunch")){
            talk.setBeginDate(parseString("12:00"));
        }else if(subject.equals("Networking Event")){
            talk.setBeginDate(parseString("17:00"));
        }
    }

    /*parse String2Date*/
    private static Date parseString(String hhmm){
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm");
        try {
            return simpleDateFormat.parse(hhmm);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    /*格式转换*/
    private static Talk parse(String msg){
        if(msg != null){
            String suffix = msg.substring(msg.lastIndexOf(' ')+1,msg.length());
            String subject = null;
            Integer m = null;
            if(suffix.contains("min")){
                 m =Integer.parseInt(suffix.replace("min",""));
                 subject = msg.substring(0,msg.lastIndexOf(" "));
            }else{
                subject = msg;
                m = null;
            }
            Talk talk = new Talk(subject,m);
            return  talk;
        }
        return null;
    }

}
